﻿using OpenQA.Selenium.Chrome;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using Microsoft.VisualBasic.Devices;


namespace NovelCrawler
{
    public partial class Form1 : Form
    {
        private int timeoutSetting;
        protected ChromeDriver browser = null;

        string startUrl = "https://www.kanshuge.org/9/9869/2303127.html";
        string endUrl = "https://www.kanshuge.org/9/9869/";

        string novelName = "重生之异能狂妻";

        string saveRootPath = AppDomain.CurrentDomain.BaseDirectory + "data\\";
        string savePath = string.Empty;
        public Form1()
        {
            InitializeComponent();

            timeoutSetting = 60;

            if (!Directory.Exists(saveRootPath))
            {
                Directory.CreateDirectory(saveRootPath);
            }

            savePath = saveRootPath + novelName + "\\";
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }
        }

        protected void checkBrowserRight()
        {
            if (browser == null)
            {
                ChromeOptions options = new ChromeOptions();
                options.AddUserProfilePreference("profile.default_content_setting_values.images", 2);
                options.AddArgument("--disable-extensions");
                browser = new ChromeDriver(GetChromeDriverService(), options, TimeSpan.FromSeconds(timeoutSetting));
            }
        }

        private static ChromeDriverService GetChromeDriverService()
        {
            return ChromeDriverService.CreateDefaultService();
        }

        /// <summary>
        /// 开始爬取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            checkBrowserRight();

            Task task = Task.Factory.StartNew(() =>
            {
                int pageIndex = 1;

                try
                {
                    browser.Navigate().GoToUrl(startUrl);
                }
                catch (OpenQA.Selenium.WebDriverTimeoutException timeoutEx)
                {
                    browser.Url = startUrl;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                while (browser.Url != endUrl)
                {
                    this.lblMsg.Invoke(new EventHandler((s1, e1) =>
                    {
                        lblMsg.Text = $"正在爬取第{pageIndex}页";
                    }));

                    DownloadDataPage(browser.Url, pageIndex.ToString().PadLeft(7, '0') + ".txt");
                    TurnPage();
                    pageIndex++;

                    Thread.Sleep(500);
                }

                this.lblMsg.Invoke(new EventHandler((s1, e1) =>
                {
                    lblMsg.Text = "全部完成";
                    MessageBox.Show("爬取完毕");
                }));
            });


        }

        void TurnPage()
        {
            var linkContent = browser.FindElementByXPath("//a[@id='linkNext']").GetAttribute("href");
            var nextUrl = linkContent;
            try
            {
                browser.Navigate().GoToUrl(nextUrl);
            }
            catch (OpenQA.Selenium.WebDriverTimeoutException timeoutEx)
            {
                browser.Url = nextUrl;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        void DownloadDataPage(string url, string fileName)
        {
            checkBrowserRight();

            string strHtml = browser.PageSource;

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(strHtml);

            HtmlAgilityPack.HtmlNode node = doc.DocumentNode.SelectSingleNode("//*[@id='htmlContent']");
            string strContent = node.InnerText.Replace("看书阁(https://www.kanshuge.org)，最快更新重生之异能狂妻最新章节！", string.Empty);

            HtmlAgilityPack.HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//*[@id='content']/div[1]/h1[1]");
            string strTitle = Environment.NewLine + titleNode.InnerText.Trim() + Environment.NewLine;

            strContent = strContent.Replace("<br>", "\r\n");

            //int startIndex = strContent.LastIndexOf("</div>");
            //strContent = strContent.Substring(startIndex + 6);

            strContent = strTitle + strContent;

            File.WriteAllText(savePath + fileName, strContent);
        }

        /// <summary>
        /// 合并
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = new DirectoryInfo(savePath);
            FileInfo[] files = dir.GetFiles();

            string targetFile = savePath + novelName + "_全.txt";

            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < files.Length; i++)
                {
                    var item = files[i];
                    var fname = item.Name;
                    //var chapter = $"第{ fname.Replace(".txt", string.Empty)}章\r\n";

                    string itemContent = File.ReadAllText(savePath + fname);
                    //itemContent = chapter + itemContent;
                    File.AppendAllText(targetFile, itemContent);
                }

                this.Invoke(new EventHandler((s1, e1) =>
                {
                    MessageBox.Show("合并完毕");
                }));
            });

        }

        /// <summary>
        /// 重新编号事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReNum_Click(object sender, EventArgs e)
        {
            FileInfo[] allTxtFiles = new DirectoryInfo(savePath).GetFiles("*.txt");

            SortAsFileName(ref allTxtFiles);
            Computer MyComputer = new Computer();
            for (int i = 0; i < allTxtFiles.Length; i++)
            {
                if (i == 0) continue;
                var txtFile = allTxtFiles[i];

                var oldName = txtFile.FullName;
                var reName = $"{ (i + 1).ToString().PadLeft(7, '0') }.txt";
                MyComputer.FileSystem.RenameFile(oldName, reName);
            }

            MessageBox.Show("重命名完成");
        }

        /// <summary>
        /// C#按文件名排序（倒序）
        /// </summary>
        /// <param name="arrFi">待排序数组</param>
        private void SortAsFileName(ref FileInfo[] arrFi)
        {
            Array.Sort(arrFi, delegate (FileInfo x, FileInfo y) { return x.Name.CompareTo(y.Name); });
        }
    }
}
